package br.uniceub.fsw.agenda.model.dao;

import br.uniceub.fsw.agenda.exception.BusinessException;
import br.uniceub.fsw.agenda.exception.DatabaseException;
import br.uniceub.fsw.agenda.exception.UniqueConstraintException;
import br.uniceub.fsw.agenda.model.vo.PessoaTelefoneVO;
import br.uniceub.fsw.agenda.model.vo.PessoaVO;
import br.uniceub.fsw.agenda.model.vo.TelefoneVO;
import java.sql.PreparedStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Bruno
 */
public class PessoaTelefoneDAO extends GenericDAO {

    public PessoaTelefoneDAO(Connection con) {
        super(con);
    }   
    
    /**
     * Retorna lista com todos os pessoaTelefones
     * @return List com objetos PessoaTelefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public List<PessoaTelefoneVO> findAll() throws DatabaseException {
        //string de consulta
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TA_PESSOATELEFONE ORDER BY ID_PESSOA");
        
        //lista pra armazenar o resultado
        List<PessoaTelefoneVO> listaRegistros = new ArrayList<PessoaTelefoneVO>();
        
        try {
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(query.toString());
            while (rs.next()) {
                PessoaTelefoneVO pessoaTelefone = new PessoaTelefoneVO();
                
                PessoaDAO pessoaDAO = new PessoaDAO(this.con);
                
                PessoaVO pessoa = pessoaDAO.findById(rs.getInt("ID_PESSOA"));
                
                pessoaTelefone.setPessoa(pessoa);

                TelefoneDAO telefoneDAO = new TelefoneDAO(this.con);
                
                TelefoneVO telefone = telefoneDAO.findById(rs.getInt("ID_TELEFONE"));
                
                pessoaTelefone.setTelefone(telefone);
                
                listaRegistros.add(pessoaTelefone);
            }
            st.close();
            rs.close();
        } catch (BusinessException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOPessoaTelefone.findAll()", ex);
        }
        return listaRegistros;
    }
    
    /**
     * Retorna associação entre pessoa e telefone
     * @param idPessoa código da pessoa
     * @param idTelefone código da telefone
     * @return List com objetos PessoaTelefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public PessoaTelefoneVO findPessoaTelefoneByTelefoneAndPessoa(Integer idPessoa, Integer idTelefone) throws DatabaseException {
        //montar consulta
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TA_PESSOATELEFONE ");
        query.append("WHERE ID_PESSOA = ? ");
        query.append("AND ID_TELEFONE = ?");
        
        PessoaTelefoneVO pessoaTelefone = new PessoaTelefoneVO();
        
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, idPessoa.toString());
            st.setString(2, idTelefone.toString());
            
            ResultSet rs = st.executeQuery();
            while (rs.next()) {
                
                PessoaDAO pessoaDAO = new PessoaDAO(this.con);
                
                PessoaVO pessoa = pessoaDAO.findById(rs.getInt("ID_PESSOA"));
                
                pessoaTelefone.setPessoa(pessoa);
                
                TelefoneDAO telefoneDAO = new TelefoneDAO(this.con);
                
                TelefoneVO telefone = telefoneDAO.findById(rs.getInt("ID_TELEFONE"));
                
                pessoaTelefone.setTelefone(telefone);
            }
            
            st.close();
            rs.close();
            
        } catch (BusinessException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOPessoaTelefone.findPessoaTelefoneByPessoaAndTelefone()", ex);
        }        
        return pessoaTelefone;
    }
    
    /**
     * Buscar lista de pessoaTelefones pela pessoa
     * @param Pessoa
     * @return List de objetos PessoaTelefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public List<PessoaTelefoneVO> findAllByPessoa(PessoaVO pessoa) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TA_PESSOATELEFONE WHERE ID_PESSOA = ?");
        
        List<PessoaTelefoneVO> listaRegistros = new ArrayList<PessoaTelefoneVO>();
            
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, pessoa.getIdPessoa().toString());
            
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                PessoaTelefoneVO pessoaTelefone = new PessoaTelefoneVO();
                
                pessoaTelefone.setPessoa(pessoa);
                
                TelefoneDAO telefoneDAO = new TelefoneDAO(this.con);
                
                TelefoneVO telefone = telefoneDAO.findById(rs.getInt("ID_TELEFONE"));
                
                pessoaTelefone.setTelefone(telefone);
                
                listaRegistros.add(pessoaTelefone);
            }

            st.close();
            rs.close();
            
        } catch (BusinessException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOPessoaTelefone.findAllByPessoa()", ex);
        }
        return listaRegistros;
    }

    /**
     * Buscar lista de pessoaTelefones por Telefone
     * @param idTelefone sigla da Telefone das pessoaTelefones que se deseja buscar
     * @return List de objetos PessoaTelefone
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public List<PessoaTelefoneVO> findAllByTelefone(TelefoneVO telefone) throws DatabaseException {
        StringBuilder query = new StringBuilder();
        query.append("SELECT * FROM TA_PESSOATELEFONE WHERE ID_TELEFONE = ?");
        
        List<PessoaTelefoneVO> listaRegistros = new ArrayList<PessoaTelefoneVO>();
            
        try {
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, telefone.getIdTelefone().toString());
            
            ResultSet rs = st.executeQuery();

            while (rs.next()) {
                PessoaTelefoneVO pessoaTelefone = new PessoaTelefoneVO();
                
                PessoaDAO pessoaDAO = new PessoaDAO(this.con);
                
                PessoaVO pessoa = pessoaDAO.findById(rs.getInt("ID_PESSOA"));
                
                pessoaTelefone.setPessoa(pessoa);
                
                pessoaTelefone.setTelefone(telefone);

                listaRegistros.add(pessoaTelefone);
            }
            st.close();
            rs.close();
        } catch (BusinessException ex) {
            ex.printStackTrace();
        } catch (SQLException ex) {
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOPessoaTelefone.findAllByTelefone()", ex);
        }
        return listaRegistros;
    }

    /**
     * Faz o insert de um novo pessoaTelefone e devolve a o id recem gerado
     * @param PessoaTelefone pessoaTelefone que se deseja inserir
     * @return ID auto-increment gerado para esse registro
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public Integer insert(PessoaTelefoneVO pessoaTelefone) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("INSERT INTO TA_PESSOATELEFONE(ID_PESSOA, ID_TELEFONE) ");
        query.append("VALUES (?,?)");
        
        //retornar id gerado
        Integer generatedId = null;
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, pessoaTelefone.getPessoa().getIdPessoa().toString());
            st.setString(2, pessoaTelefone.getTelefone().getIdTelefone().toString());
            
            st.executeUpdate();
            
            //pegar id gerado
            ResultSet rs = st.getGeneratedKeys();
            while (rs.next()) {
                generatedId = new Integer(rs.getString(1));                
            }                    
            
            return generatedId;            
        } catch (SQLException ex) {            
            ex.printStackTrace();
            if (ex.getErrorCode() == 1062) {
                throw new UniqueConstraintException(ex.getMessage(), ex);                
            }
            throw new DatabaseException("Erro no DAOPessoaTelefone.insert()", ex);            
        }      
    }
    
    /**
     * Faz o delete de um pessoaTelefone
     * @param PessoaTelefone pessoaTelefone que se deseja excluir
     * @throws br.uniceub.fsw.agenda.exception.BusinessException
     * @throws br.uniceub.fsw.agenda.exception.DatabaseException
     */
    public void delete(PessoaTelefoneVO pessoaTelefone) throws BusinessException, DatabaseException {        
        StringBuilder query = new StringBuilder();
        query.append("DELETE FROM TA_PESSOATELEFONE ");
        query.append("WHERE ID_PESSOA = ? ");
        query.append("AND ID_TELEFONE = ?");
        
        try {           
            PreparedStatement st = con.prepareStatement(query.toString());
            st.setString(1, pessoaTelefone.getPessoa().getIdPessoa().toString());
            st.setString(2, pessoaTelefone.getTelefone().getIdTelefone().toString());
            
            st.executeUpdate();
        } catch (SQLException ex) {            
            ex.printStackTrace();
            throw new DatabaseException("Erro no DAOPessoaTelefone.delete()", ex);
        }      
    }

}
